var _ = require('underscore')
  , dispatcher = require('lib/dispatcher')
  , Dispatcher = require('flux').Dispatcher;
function Scope(){
  this.$state = {};
}
_.extend(Scope.prototype,{
  state:function(){
    return this.$state
  },
  $load:function(){},
  $receive: function(nextProps){},
  $unload:function(){},
  update:function(wait) {
    if (!wait) {
      wait = 100;
    }

    if (this._timer) {
      clearTimeout(this._timer);
      this._timer = null;
    }
    var self = this;
    this._timer = setTimeout(function() {
      self.emit();
    }, wait);
  },
  _handle:function(payload){
    var payLoadName = payload.$type.toLowerCase()
    if(this['$'+payLoadName]){
      this['$'+payLoadName](payload)
    }
  },
  _emit:function(view, callback){
    if(!this.__unbind){
      if (this._timer) {
        clearTimeout(this._timer);
        this._timer = null;
      }
      view.setState(this.$state, callback ? callback : undefined);
    }
  },
  bind:function(view){
    this._handle = this._handle.bind(this)
    this.emit = this._emit.bind(this,view)
    this._dispatchToken = dispatcher.register(this._handle);

    view.dispatcher = new Dispatcher();
    view._privateDispatchToken = view.dispatcher.register(this._handle);

    if (!this.__loaded) {
      this.$load();
      this.__loaded = true;
    }
  },
  unbind:function(view){
    dispatcher.unregister(this._dispatchToken);

    view.dispatcher.unregister(view._privateDispatchToken);
    view.dispatcher = null;
    delete view.dispatcher;

    this.__unbind = true
    this.$unload();
  }
})

module.exports.Scope = Scope;
module.exports.scopeFactory = function scopeFactory(){
  return new Scope()
}
